package com.cocos.game

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.os.Handler
import android.util.Log
import com.applovin.mediation.MaxAd
import com.applovin.mediation.MaxAdFormat
import com.applovin.mediation.MaxAdListener
import com.applovin.mediation.MaxAdRevenueListener
import com.applovin.mediation.MaxError
import com.applovin.mediation.MaxReward
import com.applovin.mediation.MaxRewardedAdListener
import com.applovin.mediation.ads.MaxInterstitialAd
import com.applovin.mediation.ads.MaxRewardedAd
import com.applovin.sdk.AppLovinMediationProvider
import com.applovin.sdk.AppLovinSdk
import com.applovin.sdk.AppLovinSdkInitializationConfiguration
import com.cocos.service.SDKWrapper.SDKInterface
import java.util.concurrent.TimeUnit


class AppLovinCocosSDK : SDKInterface, MaxAdListener, MaxRewardedAdListener, MaxAdRevenueListener {

    companion object {
        @SuppressLint("StaticFieldLeak")
        var instance: AppLovinCocosSDK? = null
        private const val TAG = "AppLovinCocosSDK"
    }

    var activity: Activity? = null

    var sdkKey = "9uHgeBwag3NXva9MC23ToO3q11Ve59bF1uwg4qGltdGmCQ7OSByFZ_3b1ZF7krMlkHQo5gXzIokVDsvg1rwbr-"
    var interstitialAdUnitId = "b208842e6e617466"
    var rewardedAdUnitId = "2fccc1562e7977f1"
    var bannerAdUnitId = "1b83a60ac8976ccd"

    override fun init(context: Context?) {
        this.activity = context as Activity
        Log.i(TAG, "init: $TAG")
        instance = this

        JsbSDK.onMsg("AppLovinCocosSDK.showMediationDebugger") { args -> this.showMediationDebugger(args) }

        initialize()
    }

    private fun initialize() {
        Log.i(TAG, "initialize: ")

        val initConfig = AppLovinSdkInitializationConfiguration.builder(sdkKey).setMediationProvider(AppLovinMediationProvider.MAX).build()
        AppLovinSdk.getInstance(this.activity).initialize(initConfig) {
            Log.i(TAG, "initialize: Start loading ads")
        }
    }

    private fun showMediationDebugger(args: String) {
        Log.i(TAG, "showMediationDebugger: $args");
        AppLovinSdk.getInstance(this.activity).showMediationDebugger()
    }

    private lateinit var interstitialAd: MaxInterstitialAd
    private var interstitialRetryAttempt = 0

    private lateinit var rewardedAd: MaxRewardedAd
    private var rewardedRetryAttempt = 0

    private fun createInterstitialAd(args: String) {
        interstitialAd = MaxInterstitialAd(interstitialAdUnitId)
        interstitialAd.setListener(this)
        interstitialAd.loadAd()
        JsbSDK.sendMsg("AppLovinCocosSDKManager.load_InterstitialAd", mapOf())
    }

    private fun createRewardedAd(args: String) {
        rewardedAd = MaxRewardedAd.getInstance(rewardedAdUnitId)
        rewardedAd.setListener(this)
        rewardedAd.loadAd()
        JsbSDK.sendMsg("AppLovinCocosSDKManager.load_RewardedAd", mapOf())
    }

    override fun onAdLoaded(p0: MaxAd) {
        Log.i(TAG, "onAdLoaded: $p0")
        var adUnit = p0.adUnitId
        if (p0.format == MaxAdFormat.INTERSTITIAL) {
            interstitialRetryAttempt = 0;
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didLoad_InterstitialAd", mapOf(
                "adUnitIdentifier" to adUnit,
            ))
        } else if (p0.format == MaxAdFormat.REWARDED) {
            rewardedRetryAttempt = 0;
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didLoad_RewardedAd", mapOf(
                "adUnitIdentifier" to adUnit,
            ))
        }
    }

    override fun onAdLoadFailed(p0: String, p1: MaxError) {
        if (p0 == interstitialAdUnitId) {
            val delayMillis = TimeUnit.SECONDS.toMillis( Math.pow( 2.0, Math.min( 6.0, interstitialRetryAttempt.toDouble() ) ).toLong() )
            Handler().postDelayed({
                interstitialAd.loadAd()
                JsbSDK.sendMsg("AppLovinCocosSDKManager.load_InterstitialAd", mapOf())
            }, delayMillis )
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didFailToLoadAd_InterstitialAd", mapOf(
                "adUnitIdentifier" to p0,
                "errMessage" to p1.message
            ))
        } else if(p0 == rewardedAdUnitId) {
            rewardedRetryAttempt++
            val delayMillis = TimeUnit.SECONDS.toMillis( Math.pow( 2.0, Math.min( 6.0, rewardedRetryAttempt.toDouble() ) ).toLong() )
            Handler().postDelayed({
                rewardedAd.loadAd()
                JsbSDK.sendMsg("AppLovinCocosSDKManager.load_RewardedAd", mapOf())
            }, delayMillis )
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didFailToLoadAd_RewardedAd", mapOf(
                "adUnitIdentifier" to p0,
                "errMessage" to p1.message
            ))
        }
    }

    override fun onAdDisplayed(p0: MaxAd) {
        if (p0.format == MaxAdFormat.INTERSTITIAL) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didDisplay_InterstitialAd", mapOf(
                "networkName" to p0.networkName
            ))
        } else if (p0.format == MaxAdFormat.REWARDED) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didDisplay_RewardedAd", mapOf(
                "networkName" to p0.networkName
            ))
        }
    }

    override fun onAdHidden(p0: MaxAd) {
        if (p0.format == MaxAdFormat.INTERSTITIAL) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didHide_InterstitialAd", mapOf(
                "networkName" to p0.networkName
            ))
            interstitialAd.loadAd()
            JsbSDK.sendMsg("AppLovinCocosSDKManager.load_InterstitialAd", mapOf())
        } else if (p0.format == MaxAdFormat.REWARDED) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didHide_RewardedAd", mapOf(
                "networkName" to p0.networkName
            ))
            rewardedAd.loadAd()
            JsbSDK.sendMsg("AppLovinCocosSDKManager.load_RewardedAd", mapOf())
        }
    }

    override fun onAdClicked(p0: MaxAd) {
        if (p0.format == MaxAdFormat.INTERSTITIAL) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didClick_InterstitialAd", mapOf(
                "networkName" to p0.networkName
            ))
        } else if (p0.format == MaxAdFormat.REWARDED) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didClick_RewardedAd", mapOf(
                "networkName" to p0.networkName
            ))
        }
    }

    override fun onAdDisplayFailed(p0: MaxAd, p1: MaxError) {
        Log.i(TAG, "onAdDisplayFailed: ${p1.code} ${p1.message}")
        if (p0.format == MaxAdFormat.INTERSTITIAL) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didFail_InterstitialAd", mapOf(
                "adUnitIdentifier" to p0,
                "errMessage" to p1.message
            ))
            interstitialAd.loadAd()
            JsbSDK.sendMsg("AppLovinCocosSDKManager.load_InterstitialAd", mapOf())
        } else if (p0.format == MaxAdFormat.REWARDED) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didFail_RewardedAd", mapOf(
                "adUnitIdentifier" to p0,
                "errMessage" to p1.message
            ))
            rewardedAd.loadAd()
            JsbSDK.sendMsg("AppLovinCocosSDKManager.load_RewardedAd", mapOf())
        }
    }

    override fun onUserRewarded(p0: MaxAd, p1: MaxReward) {
        if (p0.format == MaxAdFormat.REWARDED) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.didRewardUser_RewardedAd", mapOf(
                "label" to p1.label,
                "amount" to p1.amount,
            ))
        }
    }

    // 展示插屏广告
    private fun showInterstitialAd(args:String) {
        if (interstitialAd.isReady) {
            interstitialAd.loadAd()
        }
    }

    private fun isReadyInterstitialAd(args:String) {
        if (interstitialAd.isReady) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.isReadyInterstitialAd", mapOf(
                "isReady" to true
            ))
        } else {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.isReadyInterstitialAd", mapOf(
                "isReady" to false
            ))
        }
    }

    // 展示激励广告
    private fun showRewardedAd(args: String?) {
        if (rewardedAd.isReady) {
            rewardedAd.showAd(this.activity)
        }
    }

    private fun isReadyRewardedAd(args: String?) {
        if (rewardedAd.isReady) {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.isReadyRewardedAd", mapOf(
                "isReady" to true
            ))
        } else {
            JsbSDK.sendMsg("AppLovinCocosSDKManager.isReadyRewardedAd", mapOf(
                "isReady" to false
            ))
        }
    }

    override fun onAdRevenuePaid(p0: MaxAd) {
        Log.i(TAG, "onAdRevenuePaid: $p0")
        val countryCode = AppLovinSdk.getInstance(this.activity).configuration.countryCode
        val placement = p0.placement ?: "default"
        val adNetwork = p0.networkName
        val revenue = p0.revenue
        val precision = p0.revenuePrecision
        val adFormat: String = p0.format.label

        JsbSDK.sendMsg("AppLovinCocosSDKManager.didPayRevenue", mapOf(
            "adUnitIdentifier" to p0,
            "placement" to placement,
            "networkName" to adNetwork,
            "revenue" to revenue,
            "revenuePrecision" to precision,
            "countryCode" to countryCode,
            "adFormat" to adFormat
        ));
    }
}